import type { MenuDataItem, Settings as LayoutSettings } from '@ant-design/pro-layout';
import { PageLoading } from '@ant-design/pro-layout';
import type { RequestConfig, RunTimeLayoutConfig } from 'umi';
import { history } from 'umi';
import RightContent from '@/components/RightContent';
import Footer from '@/components/Footer';
import { currentUser as queryCurrentUser, queryCurrentMenu } from './services/ant-design-pro/api';
import { message, notification } from 'antd';

const loginPath = '/user/login';
//免登录页
const publicPath = ['/user/login', '/demo/charts'];

/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
  loading: <PageLoading />,
};

/**
 * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
 * */
export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings>;
  currentUser?: API.CurrentUser | undefined;
  currentMenu?: MenuDataItem[] | undefined;
  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
  fetchUserMenu?: () => Promise<MenuDataItem[] | undefined>;
}> {
  const fetchUserInfo = async () => {
    try {
      const msg = (await queryCurrentUser()).data;
      return msg;
    } catch (error) {
      history.push(loginPath);
    }
    return undefined;
  };
  const fetchUserMenu = async () => {
    try {
      const currentMenu = (await queryCurrentMenu()).data;
      return currentMenu;
    } catch (error) {
      console.log('menu error');
    }
    return undefined;
  };

  // 如果是登录页面，不执行
  if (!publicPath.includes(history.location.pathname)) {
    const currentUser = await fetchUserInfo();
    const currentMenu = await fetchUserMenu();
    return {
      fetchUserInfo,
      fetchUserMenu,
      currentUser,
      currentMenu,
      settings: {},
    };
  }
  return {
    fetchUserInfo,
    fetchUserMenu,
    settings: {},
  };
}

// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
  return {
    rightContentRender: () => <RightContent />,
    disableContentMargin: false,
    footerRender: () => <Footer />,
    onPageChange: () => {
      const { location } = history;
      // 如果强制登录转向
      if (!initialState?.currentUser && !publicPath.includes(location.pathname)) {
        history.push(loginPath);
      }
    },
    menu: {
      defaultOpenAll: true,
    },
    //自定义菜单布局
    //menuRender: undefined,
    //自定义菜单数据 menuData (menuData: MenuDataItem[]) => MenuDataItem[]
    menuDataRender: () => {
      return initialState?.currentMenu || [];
    },
    ...initialState?.settings,
  };
};

const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队（异步任务）。',
  204: '删除数据成功。',
  400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限（令牌、用户名、密码错误）。',
  403: '用户得到授权，但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
  405: '请求方法不被允许。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请检查服务器。',
  502: '网关错误。',
  503: '服务不可用，服务器暂时过载或维护。',
  504: '网关超时。',
};

//request 错误拦截
// request全局request Error config
const errorHandler = (error: any) => {
  const { response } = error;
  console.log('response error', response);
  //服务器返回异常
  if (response && response.status) {
    // body: ReadableStream {locked: false}
    // bodyUsed: false
    // headers: Headers {append: function, delete: function, get: function, has: function, set: function, …}
    // ok: true
    // redirected: false
    // status: 200
    // statusText: "OK"
    // type: "cors"
    // url: "https://localhost:5001/api/authentication/login"
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;
    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  }

  //服务器无反应或未触达异常
  switch (response) {
    case undefined:
      notification.error({
        description: '您的网络发生异常，无法连接服务器或服务器拒绝访问！',
        message: '网络异常/服务器无响应',
      });
      break;
    case null:
      //response拦截已经处理, 必须throw 。
      console.log('业务错误');
      break;
    default:
      break;
  }

  throw error;
};

// request  请求拦截
const requestInterceptor = (url: string, options: any) => {
  return {
    url: 'http://localhost:5001' + url, // 此处可以添加域名前缀
    options: {
      ...options,
      credentials: 'include',
      requestType: 'json',
      headers: {
        'Access-Control-Allow-Origin': '*',
        authorization: 'Bearer ' + sessionStorage.getItem('token'),
      },
    },
  };
};

// request  响应拦截
// API result
// {
//   "statusCode": 500,
//   "data": null,
//   "succeeded": false,
//   "errors": "[E0003] 记录不存在",
//   "extras": null,
//   "timestamp": 1638345046886
// }
const responseInterceptor = async (response: any) => {
  if (["application/octet-stream"].includes(response.headers.get('Content-Type'))) {
    return response;
  }
  const res = await response.clone().json();
  if (res.succeeded) {
    if (res.data.success || res.data.success == null) {
      return res;
    } else {
      notification.error({
        message: `操作失败： ${res.statusCode}`,
        description: res.data.message,
      });
      message.destroy("process");
      throw new Error(res.data.message); //error ==null
    }
  }
};

//request 全局拦截配置与 useRequest 通用
export const request: RequestConfig = {
  timeout: 10000,
  errorConfig: {
    errorPage: '/exception', //默认值
    //此次适配服务器API与umi返回类型对应关系
    adaptor: (resData: any) => {
      return {
        ...resData,
        success: resData.ok,
        errorMessage: resData.message,
      };
    },
  },
  middlewares: [],
  errorHandler,
  requestInterceptors: [requestInterceptor],
  responseInterceptors: [responseInterceptor],
};
